package com.lhkj.ct.base.utils;

import com.lhkj.ct.base.constants.SystemConstants;
import com.lhkj.ct.base.enums.DataScope;
import com.lhkj.ct.base.model.LoginUser;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

/**
 * 当前登录用户
 */
@Component
public class ShiroUtil implements Serializable {

    public static boolean isRoot() {
        return getAuthUserInfo().isRoot();
    }

    public static boolean isGuest() {
        Set<String> roles = Optional.ofNullable(getAuthUserInfo())
                .map(LoginUser::getShiroRoles)
                .orElse(new HashSet<>());
        return roles.contains(SystemConstants.PLAT_ROLE_CODE);
    }

    public static DataScope getDataScope() {
        return getAuthUserInfo().getDataScope();
    }

    public static Subject getSubject() {
        return SecurityUtils.getSubject();
    }

    public static Session getSession() {
        // 当为null， 不新建session，而是返回null
        return getSubject().getSession(false);
    }

    public static LoginUser getAuthUserOfNullAble() {
        Object principal = getSubject().getPrincipal();
        return (LoginUser) principal;
    }

    public static LoginUser getAuthUserInfo() {
        Object principal = getSubject().getPrincipal();
        if (null == principal) {
            throw new UnauthenticatedException("登录已失效，请重新登录");
        }
        return (LoginUser) principal;
    }

    /**
     * 切换身份，登录后，动态更改subject的用户属性
     * @param userInfo
     */
    public static void setUser(LoginUser userInfo) {
        Subject subject = SecurityUtils.getSubject();
        PrincipalCollection principalCollection = subject.getPrincipals();
        String realmName = principalCollection.getRealmNames().iterator().next();
        PrincipalCollection newPrincipalCollection =
                new SimplePrincipalCollection(userInfo, realmName);
        subject.runAs(newPrincipalCollection);
    }
}
